using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
//using Microsoft.SharePoint.Portal.WebControls;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.Office.Server.Search;
using Microsoft.Office.Server.Search.Administration;


namespace IWCommunity.WebControls
{
    /// <summary>
    /// wanted to inherit from WebPartLoc, as it gives option of using localised strings in the web part.
    /// </summary>
    [ToolboxData("<{0}:SearchControlWebPart runat=server></{0}:SearchControlWebPart>")]
    [XmlRoot(Namespace = "IWCommunity.WebControls.WebParts")]
    public class SearchControlWebPart : Microsoft.SharePoint.WebPartPages.WebPart, INamingContainer
    {
        DropDownList scopesList;
        HtmlInputText searchTextBox;
        ImageButton goButton;
        
        private string s = string.Empty; //scope e.g. "All Sites", People etc
        private string cs = string.Empty; //context scope e.g. this site, this list, this folder etc
        private string u = string.Empty; //url to limit search to
        private string k = string.Empty; //search keywords
        private string n = string.Empty; //name of list of site

        /// <summary>
        /// set defaults in the constructor
        /// </summary>
        public SearchControlWebPart()
        {
            //setup default values
            _textBoxWidth = 170;
            _AdvImageUrl = string.Empty;
            _goImageUrl = "/_layouts/images/gosearch.gif";
            _advancedSearchUrl = "advanced.aspx";
            _resultsPageUrl = "results.aspx";
            _scopeGroup = "Search DropDown";
            _hideScopesList = ScopeDisplayOptions.Always;
            
        }

        #region Overriden Methods
        

        protected override void OnInit(EventArgs e)
        {
            //get querystring values to set defaults
            LoadQueryStringValues();
            base.OnInit(e);
        }

        protected override void CreateChildControls()
        {
            //create search table
            HtmlTable searchTable = new HtmlTable();
            searchTable.Attributes.Add("class", "ms-sbtable ms-sbtable-ex");
            searchTable.Border = 0;

            //create row for inside table
            HtmlTableRow searchRow = new HtmlTableRow();
            searchRow.Attributes.Add("class","ms-sbrow");
            searchTable.Rows.Add(searchRow);
            
            //create cell for scopes drop down list
            HtmlTableCell searchScopesCell = new HtmlTableCell();
            searchScopesCell.Attributes.Add("class","ms-sbscopes ms-sbcell");
            searchRow.Cells.Add(searchScopesCell);

            //create cell for search text box
            HtmlTableCell searchBoxCell = new HtmlTableCell();
            searchBoxCell.Attributes.Add("class", "ms-sbcell");
            searchRow.Cells.Add(searchBoxCell);

            //create cell for search go button
            HtmlTableCell searchGoCell = new HtmlTableCell();
            searchGoCell.Attributes.Add("class", "ms-sbgo ms-sbcell");
            searchRow.Cells.Add(searchGoCell);

            //create cell for Advanced Search link / button
            HtmlTableCell advSearchCell = new HtmlTableCell();
            advSearchCell.Attributes.Add("class", "ms-sbcell ms-sblink");
            searchRow.Cells.Add(advSearchCell);

            //create cell for LastCell
            HtmlTableCell lastCell = new HtmlTableCell();
            lastCell.Attributes.Add("class", "ms-sbLastcell");
            searchRow.Cells.Add(lastCell);
            			           
            //only create scopes drop down if displaymode is set for it
            bool createScopesList = ShouldDisplayScopesList();
            string ScopesclientId = string.Empty;
            if (createScopesList)
            {
                scopesList = new DropDownList();
                scopesList.ID = "scopesList"; // if (!Page.IsPostBack)
                scopesList.CssClass = "ms-sbscopes";
                scopesList.Attributes.Add("title", "Search Scope");
               
                searchScopesCell.Controls.Add(scopesList); //add drop down to drop down table cell
                LoadScopes();
            }

            //create search text box
            searchTextBox = new HtmlInputText("text");
            searchTextBox.MaxLength = 200;
            searchTextBox.ID = "txtSrch";
            searchTextBox.Style.Add("width", _textBoxWidth.ToString() + "px");
            searchTextBox.Attributes.Add("accesskey","S");
            searchTextBox.Attributes.Add("title","Enter search words");
            searchTextBox.Attributes.Add("alt","Enter search words");
            searchTextBox.Attributes.Add("class" ,"ms-sbplain");
            

            if (k.Length > 0)
                searchTextBox.Value = k;
            searchBoxCell.Controls.Add(searchTextBox); //add text box to cell in table

            //create go button control
            goButton = new ImageButton();
            goButton.ImageUrl = _goImageUrl;
            goButton.AlternateText = "Go Search";

            

            searchGoCell.Controls.Add(goButton); //add to go button cell
            //add advanced search button if web part is configured to show it
            if (_showAdvancedSearch)
            {
                HtmlAnchor advancedAnchor = new HtmlAnchor();
                advancedAnchor.HRef = GetAdvancedPageUrl();
                if (_AdvImageUrl.Length > 0) //add image instead of text
                {
                    HtmlImage advImage = new HtmlImage();
                    advImage.Alt = "Advanced Search";
                    advImage.Src = _AdvImageUrl;
                    advImage.Border = 0;
                    advancedAnchor.Controls.Add(advImage); //add image to hyperlink

                }
                else
                {
                    advancedAnchor.Title = "Advanced Search";
                    advancedAnchor.InnerText = "Advanced Search";
                }

                advSearchCell.Controls.Add(advancedAnchor); //add anchor tag to cell
             }

            //add table to control tree (all other controls are in the table control
            this.Controls.Add(searchTable);
            //add link in page to client side script which actually submits the search
            Page.ClientScript.RegisterClientScriptInclude("sbSearchScript", "/_layouts/iwcommunity/scripts/iwsearch.js");

            searchTextBox.Attributes.Add("onkeypress", "return clickButton(event,'" + goButton.ClientID + "')");
            string searchBoxSubmitScript = "function clickButton(e, buttonid){ " +
                "var evt = e ? e : window.event; " +
                "var bt = document.getElementById(buttonid); " +
                "if (bt){ " +
                "if (evt.keyCode == 13){ bt.click(); return false; }" +
                "} }";
            Page.ClientScript.RegisterClientScriptBlock(typeof(SearchControlWebPart),"textBoxEnter","<script type='text/javascript'>" + searchBoxSubmitScript + "</script>");

            base.CreateChildControls();
            //get the correct control id's now after they have been added to the control tree
            if (scopesList!=null)
                ScopesclientId = scopesList.ClientID;

            //add client side click event for submitting search
            goButton.OnClientClick = "sbmtSrch('" + searchTextBox.ClientID + "','" + ScopesclientId + "','" + GetSearchResultsPageUrl() + "');return false;";
        }

        
       
        //render the contents of the web part
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("<div id=\"SRSB\">"); //add standard search outer div
            base.RenderContents(writer);
            writer.Write("</div>");
        }
        #endregion


        #region Private Methods
        /// <summary>
        /// load defualts based on querystring values
        /// </summary>
        private void LoadQueryStringValues()
        {
            s = Page.Request.QueryString["s"];
            if (s == null)
                s = string.Empty;
            u = Page.Request.QueryString["u"];
            if (u == null)
                u = string.Empty;
            cs = Page.Request.QueryString["cs"];
            if (cs == null)
                cs = string.Empty;
            k = Page.Request.QueryString["k"];
            if (k == null)
                k = string.Empty;
            n = Page.Request.QueryString["n"];
            if (n == null)
                n = string.Empty;
           
        }

        /// <summary>
        /// load scopes, set defaults and add hidden form fields
        /// </summary>
        private void LoadScopes()
        {
            bool defaultSet = false; //has the default selection been set for the listbox
            
            if (_includeCtxScopes) // //add hidden form fields
            {
                SPList curList = SPContext.Current.List;
                SPListItem curListItem = SPContext.Current.ListItem;
                SPWeb curWeb = SPContext.Current.Web;

                if (curList != null && curListItem == null)
                {
                    //add item to drop down list
                    scopesList.Items.Add(new ListItem("This List: " + curList.Title, "This List"));
                    //add hidden field to hold URL for list
                    Page.ClientScript.RegisterHiddenField("This Listu", SPUrlUtility.CombineUrl(curWeb.Url, curList.RootFolder.Url));
                    Page.ClientScript.RegisterHiddenField("This Listn", curList.Title);
                }

                if (curWeb != null)
                {
                    //add item to drop down list
                    scopesList.Items.Add(new ListItem("This Site: " + curWeb.Title, "This Site"));
                    //add hidden field to hold URL for list
                    Page.ClientScript.RegisterHiddenField("This Siteu", curWeb.Url);
                    Page.ClientScript.RegisterHiddenField("This Siten", curWeb.Title);

                }
            }
            else if (cs.Length > 0 & u.Length > 0 & n.Length > 0 ) //use the querystring to add an option to scopes box and select it
            {
                //add item to drop down list
                scopesList.Items.Insert(0,(new ListItem(n, cs)));
                scopesList.SelectedIndex = 0;
                defaultSet = true;
                //add hidden field to hold URL for list
                Page.ClientScript.RegisterHiddenField(cs + "u", u);
                Page.ClientScript.RegisterHiddenField(cs + "n", n);
            }

            //if drop-down should be display and there is a custom search results page setup to show it
            // populate the scopes drop down box with custom site collection scopes
            if (_includeSiteScopes && SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] != null)
            {
                DisplayGroupData displayInfo = ScopesHelper.InitScopes(_scopeGroup);
                if (displayInfo != null)
                {
                    ListItem selectedScopeItem = null;
                    foreach (Scope oneScope in displayInfo.AllScopes)
                    {
                        ListItem scopeItem = new ListItem();
                        scopeItem.Text = oneScope.Name;
                        if (oneScope.AlternateResultsPage != null)
                            scopeItem.Value = GetUniqueScopedUrl(oneScope.AlternateResultsPage);
                        else
                            scopeItem.Value = "";
                            
                        //select the item in the drop down which is the default item
                        if (!defaultSet && (scopeItem.Text.ToLower() == displayInfo.DefaultScopeName.ToLower()))
                        {
                            scopeItem.Selected = true;
                            selectedScopeItem = scopeItem; //copy reference to selected item so we can unselect if needed
                        }
                        
                        scopesList.Items.Add(scopeItem);
                       
                    }

                    //if there is a querystring, then we may need to override the default selected item based on the querystring
                    if (s.Length > 0) 
                    {
                        foreach (ListItem lstItem in scopesList.Items)
                        {
                            //the we find a match, select this option
                            if (lstItem.Text.ToLower() == s.ToLower())
                            {
                                //unselect the existing item
                                if (selectedScopeItem != null)
                                    if (selectedScopeItem.Selected)
                                        selectedScopeItem.Selected = false;
                                //select the new item
                                lstItem.Selected = true;
                                break; //exit for loop
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Determine if the scopes drop-down list should be displayed
        /// </summary>
        /// <returns></returns>
        private bool ShouldDisplayScopesList()
        {
            if (_hideScopesList == ScopeDisplayOptions.Never)
                return false;
            else if (_hideScopesList == ScopeDisplayOptions.IfNoQueryString && s.Length > 0)
                return true;
            else if (_hideScopesList == ScopeDisplayOptions.IfNoQueryString && (cs.Length == 0 || n.Length == 0))
                return false;
            else return true;
        }

        /// <summary>
        /// Get URL to standard search results page
        /// </summary>
        /// <returns></returns>
        private string GetSearchResultsPageUrl()
        {
            if (SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] != null)
            {
                string sitesSearchUrl = SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] as string;
                return SPUrlUtility.CombineUrl(sitesSearchUrl, _resultsPageUrl);
            }
            else
                return SPUrlUtility.CombineUrl(SPContext.Current.Web.Url, "_layouts/osssearchresults.aspx");
        }

        /// <summary>
        /// Get URL to advanced search page
        /// </summary>
        /// <returns></returns>
        private string GetAdvancedPageUrl()
        {

            if (SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] != null)
            {
                string sitesSearchUrl = SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] as string;
                return SPUrlUtility.CombineUrl(sitesSearchUrl, _advancedSearchUrl);
            }
            else
                return SPUrlUtility.CombineUrl(SPContext.Current.Web.Url, "_layouts/osssearchresults.aspx");
        }

        /// <summary>
        /// Return URL to the search page for MOSS scope searchs with a specific URL e.g. "People" goes to peopleresults.aspx
        /// well actually for department sites, we override people on purpose so that it doesn't goto the page
        /// specified in the SSP i.e. peopleresults.
        /// </summary>
        /// <param name="searchPage">Page Url</param>
        /// <returns>full URL to search page</returns>
        private string GetUniqueScopedUrl(string searchPage)
        {
            //for department view sites, we always want people results to actually goto stand search results page
            if (searchPage.ToLower() == "peopleresults.aspx")
                return string.Empty;
            
            if (SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] != null)
            {
                string sitesSearchUrl = SPContext.Current.Site.RootWeb.AllProperties["SRCH_ENH_FTR_URL"] as string;
                    return SPUrlUtility.CombineUrl(sitesSearchUrl, searchPage);
            }
            else
                return SPUrlUtility.CombineUrl(SPContext.Current.Web.Url, "_layouts/osssearchresults.aspx");

        }

        #endregion

        #region Properties


        private bool _includeSiteScopes=true;
        [Browsable(true), Category("Miscellaneous"), WebPartStorage(Storage.Shared), FriendlyName("Include Site Scopes"), Description("Include site scopes in the scopes drop down list")]
        public bool IncludeSiteScopes
        {
            get
            {
                return _includeSiteScopes;
            }

            set
            {
                _includeSiteScopes = value;
            }
        }

        private bool _includeCtxScopes = true;
        [Browsable(true), Category("Miscellaneous"), DefaultValue(true), WebPartStorage(Storage.Shared), FriendlyName("Include Site Context Scopes"), Description("Include site context scopes in scopes drop down list")]
        public bool IncludeCtxScopes
        {
            get
            {
                return _includeCtxScopes;
            }

            set
            {
                _includeCtxScopes = value;
            }
        }

        private bool _showAdvancedSearch;
        [Browsable(true), Category("Miscellaneous"), DefaultValue(false), WebPartStorage(Storage.Shared), FriendlyName("Shows Advanced Page Link"), Description("Display Link to Advanced Search Page")]
        public bool ShowAdvancedSearch
        {
            get
            {
                return _showAdvancedSearch;
            }

            set
            {
                _showAdvancedSearch = value;
            }
        }

        private ScopeDisplayOptions _hideScopesList;
        [Browsable(true), Category("Miscellaneous"), DefaultValue(ScopeDisplayOptions.Always), WebPartStorage(Storage.Shared), FriendlyName("Display Scopes List"), Description("Display Scopes Drop Down List")]
        public ScopeDisplayOptions HideScopesList
        {
            get
            {
                return _hideScopesList;
            }

            set
            {
                _hideScopesList = value;
            }
        }

        private string _scopeGroup;
        [Browsable(true), Category("Miscellaneous"), DefaultValue("Search Dropdown"), WebPartStorage(Storage.Shared), FriendlyName("Scope Group"), Description("Default Scope Group")]
        public string ScopeGroup
        {
            get
            {
                return _scopeGroup;
            }

            set
            {
                _scopeGroup = value;
            }
        }

        private string _goImageUrl;
        [Browsable(true), Category("Miscellaneous"), DefaultValue("/_layouts/images/gosearch.gif"), WebPartStorage(Storage.Shared), FriendlyName("Go Image Url"), Description("Go Button's Image Url")]
        public string GoImageUrl
        {
            get
            {
                return _goImageUrl;
            }

            set
            {
                _goImageUrl = value;
            }
        }

        private string _AdvImageUrl;
        [Browsable(true), Category("Miscellaneous"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("Advanced Search Image Url"), Description("Advanced search button's Image Url")]
        public string AdvancedImageUrl
        {
            get
            {
                return _AdvImageUrl;
            }

            set
            {
                _AdvImageUrl = value;
            }
        }


        private string _advancedSearchUrl;
        [Browsable(true), Category("Miscellaneous"), DefaultValue("advanced.aspx"), WebPartStorage(Storage.Shared), FriendlyName("Advanced Search Page Url"), Description("Advanced Search Page Url")]
        public string AdvancedSearchUrl
        {
            get
            {
                return _advancedSearchUrl;
            }

            set
            {
                _advancedSearchUrl = value;
            }
        }

        private string _resultsPageUrl;
        [Browsable(true), Category("Miscellaneous"), DefaultValue("results.aspx"), WebPartStorage(Storage.Shared), FriendlyName("Search Results Page Url"), Description("Search Results Page Url")]
        public string ResultsPageUrl
        {
            get
            {
                return _resultsPageUrl;
            }

            set
            {
                _resultsPageUrl = value;
            }
        }

        private Int32 _textBoxWidth = 0;
        [Browsable(true), Category("Miscellaneous"), DefaultValue(170), WebPartStorage(Storage.Shared), FriendlyName("Text Box Width"), Description("Width of the Search Text Box")]
         public Int32 TextBoxWidth
        {
            get
            {
                return _textBoxWidth;
            }

            set
            {
                _textBoxWidth = value;
            }
        }


       

       




        #endregion


    }


    #region Enums
    public enum ScopeDisplayOptions
    {
        Always = 0,
        IfNoQueryString = 1,
        Never = 2
    }

    #endregion
}
